package ru.compscicenter.uno.model;

import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: Павел
 * Date: 15.10.11
 * Time: 1:53
 * Класс карты. Хранит информацию об игральной карте: цвет, значение и число очков.
 */
public class Card {
	private final int id;
	private final Color color;
	private final Type type;

	public static final int POINTS_SPECIAL = 20;
	public static final int POINTS_WILD = 50;

	public static enum Color {
		RED, GREEN, YELLOW, BLUE, ANY
	}

	public static enum Type {
		NUM_0(0), NUM_1(1), NUM_2(2), NUM_3(3), NUM_4(4), NUM_5(5), NUM_6(6), NUM_7(7), NUM_8(8), NUM_9(9),
		REVERSE(10),
		TAKE_TWO(11),
		SKIP(12),
		WILD(13),
		WILD_TAKE_FOUR(14);

		private int value;

		private static final Map<Integer, Type> lookup
				= new HashMap<Integer, Type>();
		static {
			for (Type s : EnumSet.allOf(Type.class))
				lookup.put(s.getValue(), s);
		}

		private Type(int value) {
			this.value = value;
		}

		public int getValue() {
			return value;
		}

		public static Type get(int code) {
				  return lookup.get(code);
		}
	}

	public Card(int id, Type type, Color color) {
		this.id = id;
		this.type = type;
		this.color = color;
	}

    public synchronized int getId() {
		return id;
	}

	public synchronized Color getColor() {
		return color;
	}

	public synchronized Type getType() {
		return type;
	}

	public synchronized boolean isNumeric() {
		return Type.NUM_0.getValue() <= type.getValue() && type.getValue() <= Type.NUM_9.getValue();
	}

	public synchronized boolean isColored() {
		return !isWild();
	}

    public synchronized boolean isWild() {
        return type == Type.WILD || type == Type.WILD_TAKE_FOUR;
    }

	public synchronized boolean isSpecial() {
		return Type.NUM_9.getValue() < type.getValue() && type.getValue() < Type.WILD.getValue();
	}

	public synchronized int getPoints() {
		if (isNumeric()) {
			return type.getValue();
		}
		if (isColored() && !isNumeric()) {
			return POINTS_SPECIAL;
		}
		if (!isColored()) {
			return POINTS_WILD;
		}
		return 0;
	}

	public synchronized boolean isEqual(Card card){
		return this.color == card.color && this.type == card.type;
	}

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Card card = (Card) o;

        if (id != card.id) return false;
        if (color != card.color) return false;
        if (type != card.type) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (color != null ? color.hashCode() : 0);
        result = 31 * result + (type != null ? type.hashCode() : 0);
        return result;
    }

    @Override
	public synchronized String toString() {
		return "Card{" +
				    "id = " + id +
				",\ttype = " + type.toString() +
				(isColored() ? (",\tcolor = " + color.toString()) : "") +
				'}';
	}

}
